﻿<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">



    <link rel="shortcut icon" href="../favicon.ico">
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
    <link rel="manifest" href="/manifest.json">
    <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#144287">
    <meta name="theme-color" content="#ffffff">
    <title>Dev Guide - Tempus Dominus - Bootstrap 4</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha512-MoRNloxbStBcD8z3M/2BmnT+rg4IsMxPkXaGh2zD6LGNNFE80W3onsAhRcMAMrSoyWL9xD7Ert0men7vR8LUZg==" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.css" />
    <link href="../theme/css/base.css" rel="stylesheet">
    <link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.9.0/styles/github.min.css" rel="stylesheet">
    <link href="../theme/css/tempusdominus-bootstrap-4.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.1/umd/popper.min.js" integrity="sha512-ubuT8Z88WxezgSqf3RLuNi5lmjstiJcyezx34yIU2gAHonIi27Na7atqzUZCOoY4CExaoFumzOsFQ2Ch+I/HCw==" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha512-M5KW3ztuIICmVIhjSqXe01oV2bpe248gOxqmlcYrEzAvws7Pw3z6BK0iGbrwvdrUQUhi3eXgtxp5I8PDo9YfjQ==" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.0/moment-with-locales.min.js" integrity="sha512-EATaemfsDRVs6gs1pHbvhc6+rKFGv8+w4Wnxk4LmkC0fzdVoyWb+Xtexfrszd1YuUMBEhucNuorkf8LpFBhj6w==" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.31/moment-timezone-with-data-10-year-range.min.js" integrity="sha512-Rb9RCtecTEK3SdnnQhrZx4GM1ascb2CNHybgugRDTriP/b1As79OemxeIT5qs6RMJ/fCpeJrDjtpASh7I7EKMQ==" crossorigin="anonymous"></script>
    <script>var base_url = '..';</script>

    <script src="../theme/js/base.js"></script>


    <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.9.0/highlight.min.js"></script>


    <script src="../theme/js/tempusdominus-bootstrap-4.js"></script>



</head>

<body>
    <header class="navbar navbar-expand navbar-dark flex-column flex-md-row bd-navbar">
    <a class="navbar-brand" href="https://getdatepicker.com/5-4/"><img src="https://getdatepicker.com/favicon-32x32.png" alt="home" /></a>

    <div class="navbar-nav-scroll">
        <ul class="navbar-nav bd-navbar-nav flex-row">


            <li class="nav-item">
                <a class="nav-link " href="..">Tempus Dominus Bootstrap 4</a>
            </li>



            <li class="nav-item">
                <a class="nav-link " href="../Usage/">Usage</a>
            </li>



            <li class="nav-item">
                <a class="nav-link " href="../Installing/">Installing</a>
            </li>



            <li class="nav-item">
                <a class="nav-link " href="../Functions/">Functions</a>
            </li>



            <li class="nav-item">
                <a class="nav-link " href="../Options/">Options</a>
            </li>



            <li class="nav-item">
                <a class="nav-link " href="../Events/">Events</a>
            </li>



            <li class="nav-item">
                <a class="nav-link active" href="./">Dev Guide</a>
            </li>



            <li class="nav-item">
                <a class="nav-link " href="../Extras/">Extras</a>
            </li>



            <li class="nav-item">
                <a class="nav-link " href="../FAQ/">FAQs</a>
            </li>


        </ul>
    </div>

    <ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
        <li class="nav-item">
            <a class="nav-link p-2" href="https://github.com/tempusdominus/bootstrap-4" target="_blank" rel="noopener" aria-label="GitHub">
                <span class="fa fa-github"></span>
            </a>
        </li>
    </ul>
</header>
<div class="alert alert-danger" style="font-size:1.5em;">
    <strong>Important!</strong>
    Please read this <a href="https://eonasdan.com/state-of-my-picker" target="_blank">blog post</a>.<br/>
    The Tempus Dominus projects are getting rolled back into the <a href="https://github.com/Eonasdan/tempus-dominus">orginal repo</a>. TD Bootsrap 3/4 are no longer supported.
</div>


    <div class="container-fluid">
        <div class="row">
            <div class="col-12 col-md-3 col-xl-2 bd-sidebar"><script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?serve=CK7DC5QN&placement=eonasdangithubio" id="_carbonads_js"></script>
<nav class="bd-links" id="docsNavbarContent">
    <div class="bd-toc-item active">
        <ul class="nav bd-sidenav">
            <li class="active bd-sidenav-active"><a href="#introduction">Introduction</a></li>
            <li class=""><a href="#code">Code</a></li>
            <li><a href="#private-variables">Private variables</a></li>
            <li><a href="#private-functions">Private functions</a></li>
        </ul>
    </div>
</nav></div>
            <div class="col-12 col-md-9 col-xl-8 py-md-3 pl-md-5 bd-content" role="main">
                <h1 class="bd-title">Dev Guide</h1>


<p>This guide is aimed to contributors wishing to understand the internals of the code in order to change/evolve the component. </p>
<p><strong>Note:</strong> this guide refers to <strong>version 5</strong> which is currently in alpha and will be updated as we progress</p>
<h2 id="introduction">Introduction</h2>
<p>This component consists actually of 2 subcomponent UI widgets one for the date and one for the time selection process. The developers can configure which of those are needed and also the granularity that the component will allow the users to select a date/time. Developers also choose the format that the selected date/time will be displayed in the input field.
The component uses on <code>jQuery</code>, <code>moment.js</code> libraries.</p>
<h2 id="code">Code</h2>
<h3 id="private-variables">Private variables</h3>
<ul>
<li>
<p><code>element</code> - Holds the DOM element this instance is attached to</p>
</li>
<li>
<p><code>options</code> - Holds an object with the currently set options for the specific instance of the component. Don't directly change the properties of that object use the public API methods instead. DO NOT expose this object or its properties outside of the component.</p>
</li>
<li>
<p><code>date</code> - Holds the moment object for the model value of the component. <strong>DON'T</strong> directly change this variable unless you <strong>REALLY</strong> know what you are doing. Use <code>setValue()</code> function to set it. It handles all component logic for updating the model value and emitting all the appropriate events</p>
</li>
<li>
<p><code>viewDate</code> - Holds the currently selected value that the user has selected through the widget. This is not the model value this is the view value. Changing this usually requires a subsequent call to <code>update()</code> function</p>
</li>
<li>
<p><code>unset</code> - A <code>boolean</code> variable that holds whether the components model value is set or not. Model's value starts as <code>unset = true</code> and if is either set by the user or programmatically through the api to a valid value then it is set to <code>false</code>. If subsequent events lead to an invalid value then this variable is set to <code>true</code> again. Setting this variable usually takes place in the <code>setValue()</code> function.</p>
</li>
<li>
<p><code>input</code> - Hold the DOM input element this instance is attached to</p>
</li>
<li>
<p><code>component</code> - Holds a reference to the .input-group DOM element that the widget is attached or false if it is attached directly on an input field</p>
</li>
<li>
<p><code>widget</code> - Holds a reference to the DOM element containing the widget or <code>false</code> if the widget is hidden</p>
</li>
<li>
<p><code>use24hours</code> - Holds whether the component uses 24 hours format or not. This is initialized on the <code>format()</code> function</p>
</li>
<li>
<p><code>minViewModeNumber</code> - Holds the Numeric equivalent of the options.minViewMode parameter</p>
</li>
<li>
<p><code>format</code> - Holds the current format string that is used for formatting the date model value. Note this is not the same thing as the <code>options.format</code> as the second could be set to <code>false</code> in which case the first takes the locale's <code>L</code> or <code>LT</code> value</p>
</li>
<li>
<p><code>currentViewMode</code> - Hold the state of the current viewMode for the DatePicker subcomponent</p>
</li>
<li>
<p><code>datePickerModes</code> - An array of objects with configuration parameters for the different views of the DatePicker subcomponent</p>
</li>
<li>
<p><code>viewModes</code> - An array of strings containing all the possible strings that <code>options.viewMode</code> can take through <code>viewMode()</code> public api function</p>
</li>
<li>
<p><code>directionModes</code> - An array of strings containing all the possible strings that <code>options.direction</code> can take through <code>direction()</code> public api function</p>
</li>
<li>
<p><code>orientationModes</code> - An array of strings containing all the possible strings that <code>options.orientation</code> can take through <code>orientation()</code> public api function</p>
</li>
</ul>
<h3 id="private-functions">Private functions</h3>
<h4 id="events-related">Events related</h4>
<ul>
<li>
<p><code>notifyEvent(e)</code> - Use this function when you want to send en event to listener this could be used as a filter later</p>
</li>
<li>
<p><code>stopEvent(e)</code> - Shortcut for stopping propagation of events</p>
</li>
<li>
<p><code>keydown(e)</code> - Function to trap </p>
</li>
<li>
<p><code>change(e)</code> - Listener function to track change events occurring on the <code>input</code> dom element the component is attached to</p>
</li>
<li>
<p><code>attachDatePickerElementEvents()</code> - Attaches listeners to the existing DOM elements the component is attached to. Called upon construction of each datetimepicker instance</p>
</li>
<li>
<p><code>detachDatePickerElementEvents()</code> - Detaches listeners from the DOM element the component is attached to. Called on <code>destroy()</code></p>
</li>
<li>
<p><code>attachDatePickerWidgetEvents()</code> - Attaches listeners on the components widget. Called on <code>show()</code></p>
</li>
<li>
<p><code>detachDatePickerWidgetEvents()</code> - Detaches listeners on the components widget. Called on <code>hide()</code></p>
</li>
</ul>
<h4 id="model-related">Model related</h4>
<ul>
<li>
<p><code>setValue(targetMoment)</code> - Sets the model value of the component takes a moment object. An <code>error</code> event will be emmited if the <code>targetMoment</code> does not pass the configured validations. Otherwise the <code>date</code> variable will be set and the relevant events will be fired.</p>
</li>
<li>
<p><code>isValid(targetMoment, granularity)</code> - returns <code>true</code> if the <code>targetMoment</code> moment object is valid according to the components set validation rules (<code>min/maxDates</code>, <code>disabled/enabledDates</code> and <code>daysOfWeekDisabled</code>). You may pass a second variable to check only up the the specific granularity <code>year, month, day, hour, minute, second</code></p>
</li>
</ul>
<h4 id="utilities">Utilities</h4>
<ul>
<li>
<p><code>indexGivenDates (givenDatesArray)</code> - Function that takes the array from <code>enabledDates()</code> and <code>disabledDates()</code> public functions and stores them as object keys to enable quick lookup</p>
</li>
<li>
<p><code>isInEnableDates(date)</code> - Checks whether if the given moment object exists in the <code>options.enabledDates</code> object</p>
</li>
<li>
<p><code>isInDisableDates(date)</code> - Checks whether if the given moment object exists in the <code>options.disabledDates</code> array</p>
</li>
<li>
<p><code>dataToOptions()</code> - Parses <code>data-date-*</code> options set on the input dom element the component is attached to and returns an object with them</p>
</li>
<li>
<p><code>isInFixed()</code> - Checks if the dom element or its parents has a fixed position css rule.</p>
</li>
<li>
<p><code>parseInputDate(date)</code> - Parses a date parameter with moment using the component's <code>options.format</code> and <code>options.useStrict</code>. It returns a <code>moment</code> object or false if <code>parsedMoment#isValid()</code> returns <code>false</code>. Use this to parse date inputs from outside the component (public API calls).</p>
</li>
<li>
<p><code>init()</code> - Initializes the component. Called when the component instance is created</p>
</li>
</ul>
            </div>
        </div>
    </div>


    <script>
        if (top !== self) { top.location.replace(self.location.href); }
        if (location.hostname !== "localhost" && location.hostname !== "127.0.0.1") {
            (function (i, s, o, g, r, a, m) {
                i['GoogleAnalyticsObject'] = r;
                i[r] = i[r] ||
                    function () {
                        (i[r].q = i[r].q || []).push(arguments);
                    }, i[r].l = 1 * new Date();
                a = s.createElement(o),
                    m = s.getElementsByTagName(o)[0];
                a.async = 1;
                a.src = g;
                m.parentNode.insertBefore(a, m);
            })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');

            ga('create', 'UA-47462200-1', 'eonasdan.github.io');
            ga('send', 'pageview');
        }
    </script>
    </body>
</html>